import React from 'react'
import styles from './merchant-definition/merchant-definition.less'
import request from "./../utils/request.js"
import areas from './../mock/areas.js'
import { 
    Breadcrumb,Icon,Button,DatePicker,Select 
} from 'antd'
import points from "./../mock/beijing_heatmap_points.js"
import pointImg from './../assets/point.png'
import md5 from 'js-md5'
import {connect} from 'dva'
import EditMerchantDefinition from './merchant-definition/EditMerchantDefinition.js'
import DataMerchantDefinition from './merchant-definition/DataMerchantDefinition.js'

class MerchantDefinition extends React.Component{
    constructor(props){
        super(props);
        this.bmap=React.createRef();
        this.state={         
            bmap:null,
            startDate:"",
            endDate:"",
            currentProvince:"",
            points:[],
            areas:areas,
            currentCircles:{},
            editMerchantDefinitionVisible: false,
            merchantDefinition:{
                merchantName:"merchantName",
                geoType:"geoType",
                area:"500",
                bounds:"1,2,5",
                level:"C",                     //level是mysql关键字,加个下划线避免变量名与关键字冲突
                description:"description"    
            },
            merchantDefinitions:[]
        }
        //这种方式可以配合服务端混合使用
        request("http://localhost:8094/merchantDefinition/list?size=8&offset=0",{},(da)=>{ //成功
            this.setState({
                merchantDefinitions:da
            })    
        },(err)=>{
            console.log(err);
        });
    }
    render(){
        return (
        	<div  className={`${styles.pageContent} ${styles.merchantDefinition}`}>
        		{/* 头部 */}
                <div className={styles.pageHeader} style={{backgroundColor:"#fff"}}>
                    <Breadcrumb>
                        <Breadcrumb.Item href="/">
                            <Icon type="home" />
                        </Breadcrumb.Item>
                        <Breadcrumb.Item>
                            使用频次热力图 
                        </Breadcrumb.Item>
                    </Breadcrumb>
                </div>
            	{/* 百度地图热力图 这个是页面核心功能，应该和下面的代码一样独立成组件 */}
                <div id="bmap" className={styles.bmap} ref={this.bmap}></div>
                
                <EditMerchantDefinition
                    visible={this.state.editMerchantDefinitionVisible}
                    merchantDefinition={this.state.merchantDefinition}
                    onCreate={this.handleCreate.bind(this)}
                    onCancel={this.handleCancel.bind(this)}
                 ></EditMerchantDefinition>

               
                <DataMerchantDefinition
                    da={this.state.merchantDefinitions}
                    onLoadData={this.handleLoadData.bind(this)}
                 />
                            
           	</div>
        )
    }
    componentDidMount(){
        var $this=this;
        var map=new window.BMap.Map(this.bmap.current,{
            minZoom:12,
            maxZoom:19
        });
        map.centerAndZoom(new window.BMap.Point(116.395645038,39.9299857781), 14);                            
        map.addControl(new window.BMap.NavigationControl({
            anchor: window.BMAP_ANCHOR_TOP_LEFT
        }));                           
        map.enableScrollWheelZoom(true); 
        $this.setState({
            bmap:map
        });

        //服务端需要使用elasticsearch，暂时未能提供，这里前端使用GeoUtils计算。
        var allMapPoints=points.data.map((item,index)=>{
            return new window.BMap.Point(item.longitude,item.latitude);
        });
        
        //批量点绘制工具，批量点绘制工具与单个打点不同，批量处理点图片可以提高性能
        var markerManager=new window.BMapLib.MarkerManager(map,{      
            borderPadding:10
        });

        //自定义点形状
        var mapPointImg = new window.BMap.Icon(pointImg, new window.BMap.Size(11, 15)); 

        //绘制工具样式
        var styleOptions = {
            strokeColor:"red",           //边线颜色。
            fillColor:"red",             //填充颜色。当为空时，圆将没有填充效果。
            strokeWeight: 3,             //边线的宽度，以像素为单位。
            strokeOpacity: 0.8,          //边线透明度，取值范围0 - 1。
            fillOpacity: 0.1,            //填充的透明度，取值范围0 - 1。
            strokeStyle: 'dashed'        //边线的样式，solid或dashed。
        }

        //实例化鼠标绘制工具，扩展地图
        var drawingManager = new window.BMapLib.DrawingManager(map, {
            isOpen: false,                          
            enableDrawingTool: true,               
            drawingToolOptions: {
                anchor: window.BMAP_ANCHOR_TOP_RIGHT,      
                offset: new window.BMap.Size(5, 5),        
                drawingModes: [ window.BMAP_DRAWING_CIRCLE, window.BMAP_DRAWING_POLYGON,window.BMAP_DRAWING_RECTANGLE ]
            },
            circleOptions: styleOptions,            
            polygonOptions: styleOptions,         
            rectangleOptions: styleOptions          
        });  

        //事件监听
        drawingManager.addEventListener("overlaycomplete", function(evt,overlay,drawingMode) {          
            switch(evt.drawingMode){   
                case "circle":    
                    var center=evt.overlay.getCenter();
                    var circleKey=md5(center.lng+"_"+center.lat);  //当前圆图层的唯一标志，相同参数删除时再计算一次找到当前markers引用 
                    var tempMarkers=[];                    
                    var tempMarker;               
                    for(var i=0;i<allMapPoints.length;i++){     
                        if(window.BMapLib.GeoUtils.isPointInCircle(allMapPoints[i],evt.overlay)){ 
                            tempMarker=new window.BMap.Marker(allMapPoints[i],{icon: mapPointImg});
                            tempMarkers.push(tempMarker)
                        }
                    }
                    //此处是最大的性能损耗，如果是有elasticsearch可以直接传递圆特征参数到服务端，
                    markerManager.addMarkers(tempMarkers,12,19);
                    markerManager.showMarkers();
                    $this.setState({
                        currentCircles:{
                            [circleKey]:tempMarkers,
                            ...$this.state.currentCircles
                        }
                    });
                    break;
                case "rectangle":    
                    var pps = evt.overlay.getPath();                    //Points数组
                    var bounds=new window.BMap.Bounds(pps[3],pps[1]);   //Bounds(sw: Point, ne: Point) 
                    var tempMarkers=[];                    
                    for(var i=0;i<allMapPoints.length;i++){     
                        if(window.BMapLib.GeoUtils.isPointInRect(allMapPoints[i],bounds)){  //圆和多边形传递的都是图形实例，就这个传递的是边界
                            tempMarkers.push(new window.BMap.Marker(allMapPoints[i],{icon: mapPointImg}))
                        }
                    }
                    markerManager.addMarkers(tempMarkers,12,19);
                    markerManager.showMarkers();
                    break;
                case "polygon":                 
                    var tempMarkers=[];                    
                    for(var i=0;i<allMapPoints.length;i++){     
                        if(window.BMapLib.GeoUtils.isPointInPolygon(allMapPoints[i],evt.overlay)){
                            tempMarkers.push(new window.BMap.Marker(allMapPoints[i],{icon: mapPointImg}))
                        }
                    }
                    markerManager.addMarkers(tempMarkers,12,19);
                    markerManager.showMarkers();
                    break;
                default:
                    ;
            }  
            //TODO:为当前覆盖物添加菜单，非单例，每次需要重新var <p style='margin-top:10px;' class='fa fa-envelope'>&nbsp;显示热力图</p>
            var overlayMenu=new window.BMap.ContextMenu();
            overlayMenu.addItem(new window.BMap.MenuItem("<p style='padding-top:5px;' class='fa fa-remove'>&nbsp;删除图形</p>",removeOverlay.bind(evt,evt.overlay,evt.drawingMode)));       
            overlayMenu.addItem(new window.BMap.MenuItem("<p style='padding-top:5px;' class='fa fa-file'>&nbsp;导出数据</p>",exportOverlay.bind(evt,evt.overlay,evt.drawingMode)));
            overlayMenu.addItem(new window.BMap.MenuItem("<p style='padding-top:5px;' class='fa fa-check-circle'>&nbsp;定义商圈</p>",merchantDefinitionFromOverlay.bind(evt,evt.overlay,evt.drawingMode)));
            evt.overlay.addContextMenu(overlayMenu);       
            drawingManager.close();                   
        });
        //删除图层
        var removeOverlay = function(overlay,drawingMode){               
            switch(drawingMode){
                case "circle": 
                    var center=overlay.getCenter();             
                    var circleKey=md5(center.lng+"_"+center.lat); //与添加是呼应，删除先删除对应overlay中的点
                    var markers=$this.state.currentCircles[circleKey];
                    if(markers && markers.length>0){
                        markers.forEach(function(item,index){
                            map.removeOverlay(item);          
                            //markerManager.removeMarker(item);   //理论上批量删除点，此方法最符合语义，这个方法有bug
                        });
                    } 
                    //神一样的网友，神一样的写法
                    $this.setState((prevState, props) => {
                        delete prevState.currentCircles[circleKey]
                        return prevState;
                    },()=>{
                        console.log($this.state);
                    });
                    break;
                case "rectangle":                               
                    console.log("rectangle");   
                    break;
                case "polygon":
                    console.log("polygon");   
                    break;
                default:
                    ;
            } 
            map.removeOverlay(overlay);          
        };
        //导出数据
        var exportOverlay=function(overlay,drawingMode){
            switch(drawingMode){
                case "circle":                  
                    console.log("导出数据：circle");   
                    break;
                case "rectangle":                               
                    console.log("导出数据：rectangle");   
                    break;
                case "polygon":
                    console.log("导出数据：polygon");   
                    break;
                default:
                    ;
            } 
        }
        //定义商圈
        var merchantDefinitionFromOverlay=function(overlay,drawingMode){
            switch(drawingMode){
                case "circle":  
                    //overlay.getCenter().lng+","+overlay.getCenter().lat，圆的中心点坐标，更多api参考百度地图
                    $this.setState({
                        editMerchantDefinitionVisible:true,
                        merchantDefinition:{
                            merchantName:"",
                            geoType:"circle",
                            area:overlay.getRadius()*3.1415926,
                            bounds:overlay.getBounds().getSouthWest().lng+","+overlay.getBounds().getSouthWest().lat+" - "+overlay.getBounds().getNorthEast().lng+","+overlay.getBounds().getNorthEast().lat,
                            _level:"C",                    
                            description:""    
                        }
                    })
                    break;
                case "rectangle":                               
                    console.log("定义商圈：rectangle");   
                    break;
                case "polygon":
                    console.log("定义商圈：polygon");   
                    break;
                default:
                    ;
            } 
        }
    }
    handleCreate(values){  //业务方法：处理添加，我的写法与ant design官方差别很大
        this.setState({
            editMerchantDefinitionVisible:false,
            merchantDefinition:{
                inputBy:this.props.user.name,
                ...values
            }
        },()=>{
            request("http://localhost:8094/merchantDefinition/add",this.state.merchantDefinition,(da)=>{ //成功  
                this.handleLoadData(1);
            },(err)=>{
                console.log(err);
            });
        });
    }
    handleCancel(){   //业务方法，模态框取消
        this.setState({
            editMerchantDefinitionVisible:false
        })
    }
    handleLoadData(page){
        request("http://localhost:8094/merchantDefinition/list?size=8&offset="+(page-1)*8,{},(da)=>{ //成功
            this.setState({
                merchantDefinitions:da
            })    
        },(err)=>{
            console.log(err);
        });
    }
}
export default connect((state)=>{
    return {
        user:state.app.user
    };
})(MerchantDefinition)

/**
 *  1> 在传统JavaScript api开发中如何解决react组件this指针问题，当前项目我粗暴处理了一个$this；
 *  2> 以计算属性方式设置react state属性，普通方式设置不上去；
 *  3> 
 *  4> react不需要$emit，父组件直接传递回调函数给子组件，子组件通过this.props.callbacl(args),
 *      部分兄弟觉得“I love using Vue's event bus. $emit, $on, and $off are very powerful.”于是他开发了一个npm项目，
 *      https://www.npmjs.com/package/react-emit使得react也支持这个，我这里觉得不是很有必要。
 *  5> 在模态框调用form.create()后的组件后，如何在使用模态框的父组件拿到组件的form属性，
 *      从父组件->模态框->Form组件，我当前的处理办法是子模态框组件一级传递数据到handleCreate处理，
 *      但是ant design官方网址给的例子不是这么玩的，他是通过wrappedComponentRef={this.saveFormRef}
 *      在saveFormRef注入formRef给父组件
 *      saveFormRef = formRef => {
 *          this.formRef = formRef;
 *      };
 *      this.formRef是父组件的静态属性，formRef指向EditMerchantDefinition，其props.form就是子组件中的表单。
 *      这种写法太过诡异...............
 */